package meatslope2.gameengine.engine;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import meatslope2.application.GameApplication;
import android.opengl.GLSurfaceView;

/**
 * Controls what is drawn within a given {@link GLSurfaceView}.  Also takes in an {@link IRendererListener}
 * to notify when the surface has been created.
 * @author Mitchell Thelen
 *
 */
public class EngineRenderer implements GLSurfaceView.Renderer 
{
	// ===========================================================
	// Members
	// ===========================================================
	private final IRendererListener rendererListener;
	private final Engine engine;
	
	// ===========================================================
	// Constructors
	// ===========================================================
	public EngineRenderer(GameApplication game, Engine engine)
	{
		this.rendererListener = game;
		this.engine = engine;
	}
	
	// ===========================================================
	// Methods for/from SuperClass/Interfaces
	// ===========================================================
	
	public void onDrawFrame(final GL10 pGL) 
	{
		try 
		{
			this.engine.onDrawFrame(pGL);
		} 
		catch (final InterruptedException e){} //This is expected
	}
	
    /**
     * Called whenever the surface is created.  This happens at startup, and
     * may be called again at runtime if the device context is lost (the screen
     * goes to sleep, etc).  This function must fill the contents of vram with
     * texture data and (when using VBOs) hardware vertex arrays.
     */
    public void onSurfaceCreated(GL10 pGL, EGLConfig arg1) 
    {
        /*
        * Some one-time OpenGL initialization can be made here probably based
        * on features of this particular context
        */
       pGL.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);

       pGL.glClearColor(0.5f, 0.5f, 0.5f, 1);
       pGL.glShadeModel(GL10.GL_FLAT);
       pGL.glDisable(GL10.GL_DEPTH_TEST);
       pGL.glEnable(GL10.GL_TEXTURE_2D);
       /*
        * By default, OpenGL enables features that improve quality but reduce
        * performance. One might want to tweak that especially on software
        * renderer.
        */
       pGL.glDisable(GL10.GL_DITHER);
       pGL.glDisable(GL10.GL_LIGHTING);

       pGL.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
       
		if(rendererListener != null)
			rendererListener.onSurfaceCreated(pGL);
    }

    /* Called when the size of the window changes. */
    public void onSurfaceChanged(GL10 gl, int width, int height) 
	{
        gl.glViewport(0, 0, width, height);

        /*
         * Set our projection matrix. This doesn't have to be done each time we
         * draw, but usually a new projection needs to be set when the viewport
         * is resized.
         */
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        //gl.glOrthof(200.0f, 200 + width, 0.0f, height, 0.0f, 1.0f);
        
        gl.glShadeModel(GL10.GL_FLAT);
        gl.glEnable(GL10.GL_BLEND);
        gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
        gl.glColor4x(0x10000, 0x10000, 0x10000, 0x10000);
        gl.glEnable(GL10.GL_TEXTURE_2D);
        
        //Finally, reset reference to game dimensions
        rendererListener.onSurfaceChanged();
    }
}
